-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Store both the rounded and unrounded node size in Node #9923
Conversation
…that given whatever the constraints are text will only wrap after it's used the maximum amount of available horizontal space. However then when the layout size is returned, before the Node size is set the layout coordinates are rounded, sometimes changing the size of the Node. This means that the text may no longer fit the horizontal available space and wrap onto a new line. But since the layout algorithm hasn't alloted any vertical space for this new line, the text on this new line dissappears. The commit adds a flag `no_rounding` to `ContentSize` that tells the layout algorithm not to round the size of the node, avoiding this problem. Rounding is used eliminate pixel wide gaps between nodes that should be touching edge to edge, but this isn't necessary for text nodes as they don't have solid edges.
ContentSize
.ContentSize
ContentSize
ContentSize
Renamed the `no_rounding` field to `rounding` and changed its type to `SizeRounding`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense to me. I think the general principle is:
Rounding (pixel-grid alignment) should never affect layout, and should be for rendering only.
For text, I suspect that might mean passing the unrounded value into text layout, and then clipping to the rounded value when rendering.
Yeah it needs a lot of thinking about. I also considered just adding both the rounded and unrounded sizes to Node. I was feeling before that it would be a bit redundant and a waste of memory, but maybe it's the better solution. |
In theory, you shouldn't need to perform text layout again once Taffy's layout has completed. But I'm guessing our current text infrastructure doesn't allow us to reuse the result? We ended up having to store both in Taffy, because otherwise we can't cache results from previous layout runs (as they might round differently if their parents lay out differently and they end up in a different absolute position within the viewport). |
I tested every example at scale factor The ones that had differences were
For other scale factors, I only tested the examples listed above. At scale factor Seemingly the same story at |
Instead, store the both the unrounded and rounded sizes in `Node`.
ContentSize
Switched approach to storing both the rounded and unrounded node sizes in |
I think the gaps should be gone now with the new approach. Text can use the unrounded bounds for layout calculations but the size of any node containing text will remain rounded, so there shouldn't be any gaps in the layout. How does it look for you now? |
Co-authored-by: Rob Parrett <robparrett@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love how simple this version is.
Did some more testing using my collection of screenshot diffing scripts vs the base commit
- All examples at SF 2
- UI examples at SF 1, 4/3, 5/3
Looks good to me. Minor changes in text wrapping behavior that seem more correct, and seemingly no unintended consequences.
# Objective Text bounds are computed by the layout algorithm using the text's measurefunc so that text will only wrap after it's used the maximum amount of available horizontal space. When the layout size is returned the layout coordinates are rounded and this sometimes results in the final size of the Node not matching the size computed with the measurefunc. This means that the text may no longer fit the horizontal available space and instead wrap onto a new line. However, no glyphs will be generated for this new line because no vertical space for the extra line was allocated. fixes bevyengine#9874 ## Solution Store both the rounded and unrounded node sizes in `Node`. Rounding is used to eliminate pixel-wide gaps between nodes that should be touching edge to edge, but this isn't necessary for text nodes as they don't have solid edges. ## Changelog * Added the `rounded_size: Vec2` field to `Node`. * `text_system` uses the unrounded node size when computing a text layout. --------- Co-authored-by: Rob Parrett <robparrett@gmail.com>
Objective
Text bounds are computed by the layout algorithm using the text's measurefunc so that text will only wrap after it's used the maximum amount of available horizontal space.
When the layout size is returned the layout coordinates are rounded and this sometimes results in the final size of the Node not matching the size computed with the measurefunc. This means that the text may no longer fit the horizontal available space and instead wrap onto a new line. However, no glyphs will be generated for this new line because no vertical space for the extra line was allocated.
fixes #9874
Solution
Store both the rounded and unrounded node sizes in
Node
.Rounding is used to eliminate pixel-wide gaps between nodes that should be touching edge to edge, but this isn't necessary for text nodes as they don't have solid edges.
Changelog
rounded_size: Vec2
field toNode
.text_system
uses the unrounded node size when computing a text layout.